<script setup>
	import { ref } from 'vue'
	import { message } from 'ant-design-vue'
	import { format } from 'sql-formatter'
	import { useCustomQueryStore } from '@/views/plugin/dashboard/store/customQuery'
	import {
		BulbOutlined,
		CalculatorOutlined,
		FileTextOutlined,
		FormatPainterOutlined,
		FunctionOutlined,
		PlayCircleOutlined,
		RobotOutlined,
		SaveOutlined
	} from '@ant-design/icons-vue'
	import smCrypto from 'sm-crypto'
	import datasetApi from '@/views/plugin/dashboard/api/datasetApi'
	import PromptTemplate from './PromptTemplate.vue'
	import SqlTemplateManager from './SqlTemplateManager.vue'
	import AggregationFunctions from './AggregationFunctions.vue'
	import FormulaHelper from './FormulaHelper.vue'

	const sm4 = smCrypto.sm4

	// SM4 CBC模式加密
	const doSm4Encrypt = (msgString, key) => {
		return sm4.encrypt(msgString, key)
	}
	const store = useCustomQueryStore()

	const props = defineProps({
		selectedTables: {
			type: Array,
			required: true
		},
		tableList: {
			type: Array,
			required: true
		},
		editor: {
			type: Object,
			required: true
		}
	})
	const emit = defineEmits(['update:selectedTables', 'onSave'])

	// 主题状态
	const isDarkTheme = ref(false)

	// 切换主题
	const toggleTheme = () => {
		isDarkTheme.value = !isDarkTheme.value
		if (props.editor && props.editor.cminstance) {
			props.editor.cminstance.setOption('theme', isDarkTheme.value ? 'dracula' : 'idea')
		}
	}

	// 组件引用
	const sqlTemplateManagerRef = ref(null)
	const aggregationFunctionsRef = ref(null)
	const formulaHelperRef = ref(null)

	// 处理模板应用事件
	const handleTemplateApplied = () => {
		// 更新store中的SQL
		if (props.editor && props.editor.cminstance) {
			store.updateSql(props.editor.cminstance.getValue())
		}
	}

	// 处理函数应用事件
	const handleFunctionApplied = () => {
		// 更新store中的SQL
		if (props.editor && props.editor.cminstance) {
			store.updateSql(props.editor.cminstance.getValue())
		}
	}

	// 处理公式应用事件
	const handleFormulaApplied = () => {
		// 更新store中的SQL
		if (props.editor && props.editor.cminstance) {
			store.updateSql(props.editor.cminstance.getValue())
		}
	}

	// 格式化SQL
	const formatSql = () => {
		if (props.editor && props.editor.cminstance) {
			const cm = props.editor.cminstance
			let sql = cm.getValue()

			try {
				// 保存自定义占位符的映射
				const placeholderMap = new Map()
				let placeholderCounter = 0

				// 定义所有需要处理的占位符类型
				const placeholderPatterns = [
					/\$\{[^}]+\}/g, // ${...} 格式的占位符
					/\{[^}]+\}/g // {...} 格式的占位符
				]

				// 处理所有类型的占位符
				placeholderPatterns.forEach((pattern) => {
					const matches = sql.match(pattern) || []
					matches.forEach((placeholder) => {
						// 避免重复处理同一个占位符
						if (!Array.from(placeholderMap.values()).includes(placeholder)) {
							const tempMarker = `PLACEHOLDER_${placeholderCounter}_TEMP`
							placeholderMap.set(tempMarker, placeholder)
							// 使用全局替换确保所有相同的占位符都被替换
							sql = sql.replace(new RegExp(escapeRegExp(placeholder), 'g'), tempMarker)
							placeholderCounter++
						}
					})
				})

				// 格式化处理后的SQL
				let formatted = format(sql, {
					language: 'mysql',
					keywordCase: 'upper',
					functionCase: 'upper'
				})

				// 恢复占位符
				placeholderMap.forEach((originalPlaceholder, tempMarker) => {
					formatted = formatted.replace(new RegExp(escapeRegExp(tempMarker), 'g'), originalPlaceholder)
				})

				cm.setValue(formatted)
				// 更新store中的SQL
				store.updateSql(formatted)
				message.success('SQL格式化成功')
			} catch (error) {
				console.error('SQL格式化失败:', error)
				message.error('SQL格式化失败，请检查SQL语法')
			}
		}
	}

	// 转义正则表达式特殊字符的辅助函数
	const escapeRegExp = (string) => {
		return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
	}

	// 加密SQL
	const encryptSql = (sql) => {
		// 使用固定的16字节密钥
		const key = '0123456789abcdeffedcba9876543210'
		return doSm4Encrypt(sql, key)
	}

	// 运行SQL
	const runSql = async () => {
		if (!props.editor || !props.editor.cminstance) return

		const sql = props.editor.cminstance.getValue()
		if (!sql.trim()) {
			message.warning('SQL语句不能为空')
			return
		}

		// 显示加载提示，在try块外定义hide变量
		let hide = null
		try {
			hide = message.loading('正在执行SQL查询...', 0)
			// 加密SQL
			const encryptedSql = encryptSql(sql)
			// 调用API执行SQL
			const result = await datasetApi.executeSql({
				sql: encryptedSql,
				dataConnectorId: store.formData.dataConnectorId
			})
			// 更新store中的查询结果
			store.updateQueryResult(result)
			// 关闭加载提示
			if (hide) {
				hide()
			}
			// message.success('SQL执行成功')
		} catch (error) {
			// 确保hide存在时才调用
			if (hide) {
				hide()
			}
			message.error('SQL执行失败：' + error.message)
		}
	}

	defineExpose({
		isDarkTheme
	})
</script>

<template>
	<div class="sql-toolbar">
		<a-space :size="'small'">
			<!-- 工具栏图标按钮组 -->
			<div class="toolbar-icons">
				<!-- 主题切换 -->
				<a-tooltip :title="isDarkTheme ? '切换亮色主题' : '切换暗色主题'">
					<a-button type="text" @click="toggleTheme">
						<template #icon>
							<BulbOutlined />
						</template>
					</a-button>
				</a-tooltip>

				<!-- SQL模板管理器 -->
				<a-tooltip title="SQL模板">
					<a-popover :overlayStyle="{ width: '520px' }" placement="bottomLeft" trigger="click">
						<template #content>
							<SqlTemplateManager
								ref="sqlTemplateManagerRef"
								:editor="props.editor"
								:selected-tables="props.selectedTables"
								@template-applied="handleTemplateApplied"
							/>
						</template>
						<a-button type="text">
							<template #icon><FileTextOutlined /></template>
						</a-button>
					</a-popover>
				</a-tooltip>

				<!-- 聚合函数组件 -->
				<a-tooltip title="聚合函数">
					<a-popover :overlayStyle="{ width: '470px' }" placement="bottomLeft" trigger="click">
						<template #content>
							<AggregationFunctions
								ref="aggregationFunctionsRef"
								:editor="props.editor"
								@function-applied="handleFunctionApplied"
							/>
						</template>
						<a-button type="text">
							<template #icon><FunctionOutlined /></template>
						</a-button>
					</a-popover>
				</a-tooltip>

				<!-- 公式助手组件 -->
				<a-tooltip title="常用公式">
					<a-popover :overlayStyle="{ width: '520px' }" placement="bottomLeft" trigger="click">
						<template #content>
							<FormulaHelper
								ref="formulaHelperRef"
								:data-connector-id="store.formData.dataConnectorId"
								:editor="props.editor"
								@formula-applied="handleFormulaApplied"
							/>
						</template>
						<a-button type="text">
							<template #icon><CalculatorOutlined /></template>
						</a-button>
					</a-popover>
				</a-tooltip>

				<!-- 格式化按钮 -->
				<a-tooltip title="格式化SQL">
					<a-button type="text" @click="formatSql">
						<template #icon><FormatPainterOutlined /></template>
					</a-button>
				</a-tooltip>

				<!-- 运行SQL按钮 -->
				<a-tooltip title="运行SQL">
					<a-button type="text" @click="runSql" class="run-btn">
						<template #icon><PlayCircleOutlined /></template>
					</a-button>
				</a-tooltip>

				<!-- AI提示词生成器 -->
				<a-tooltip title="AI提示词生成器">
					<a-popover :overlayStyle="{ width: '850px' }" placement="right" trigger="click">
						<template #content>
							<PromptTemplate
								:data-connector-id="store.formData.dataConnectorId"
								:sql="props.editor?.cminstance?.getValue() || ''"
								:params="[]"
							/>
						</template>
						<a-button type="text" class="ai-btn">
							<template #icon><RobotOutlined /></template>
						</a-button>
					</a-popover>
				</a-tooltip>
				<a-tooltip title="保存配置">
					<a-button type="text" @click="emit('onSave', store.formData)">
						<template #icon>
							<save-outlined />
						</template>
					</a-button>
				</a-tooltip>
			</div>
		</a-space>
	</div>
</template>

<style scoped>
	.sql-toolbar {
		padding: 10px 16px;
		border-bottom: 1px solid #e8e8e8;
		background-color: #ffffff;
		display: flex;
		align-items: center;
		justify-content: space-between;
		box-shadow: 0 1px 2px rgba(0, 0, 0, 0.03);
	}

	.toolbar-icons {
		display: flex;
		align-items: center;
		gap: 8px;
	}

	.toolbar-icons :deep(.ant-btn) {
		width: 32px;
		height: 32px;
		padding: 0;
		display: flex;
		align-items: center;
		justify-content: center;
		border-radius: 2px;
		transition: all 0.3s;
	}

	.toolbar-icons :deep(.ant-btn:hover) {
		color: #1890ff;
		background-color: rgba(24, 144, 255, 0.1);
	}

	.toolbar-icons :deep(.anticon) {
		font-size: 16px;
	}

	.toolbar-icons :deep(.run-btn) {
		background-color: #f0f7ff;
		color: #1890ff;
	}

	.toolbar-icons :deep(.run-btn:hover) {
		background-color: #e6f4ff;
		color: #1890ff;
	}

	.toolbar-icons :deep(.ai-btn) {
		background-color: #f6f0ff;
		color: #722ed1;
	}

	.toolbar-icons :deep(.ai-btn:hover) {
		background-color: #f2e8ff;
		color: #722ed1;
	}

	:deep(.ant-btn) {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		gap: 4px;
	}

	:deep(.ant-space) {
		display: flex;
		flex-wrap: wrap;
		gap: 8px;
	}

	.prompt-template-container {
		padding: 16px;
		border-radius: 2px;
	}
</style>
